package com.xinqi.modules.chat.chat.message.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.user.Account;
import com.xinqi.common.core.constant.ChatConstants;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.modules.chat.chat.group.service.impl.ChatGroupMessageService;
import com.xinqi.modules.chat.chat.message.convert.ChatTopMessageConvert;
import com.xinqi.modules.chat.chat.message.domain.ChatTopMessageEntity;
import com.xinqi.modules.chat.chat.message.dto.req.ChatMessageCancelTopDTO;
import com.xinqi.modules.chat.chat.message.dto.req.ChatMessageTopDTO;
import com.xinqi.modules.chat.chat.message.dto.rsp.ChatTopMessageResultDTO;
import com.xinqi.modules.chat.chat.message.manager.ChatTopMessageManager;
import com.xinqi.modules.chat.chat.message.service.ChatTopMessageService;
import io.rong.util.CodeUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 聊天消息置顶表服务层实现
 *
 * @author: yyzhen
 * @date: 2023/06/29
 */
@Service("chatTopMessageService")
@RequiredArgsConstructor
public class ChatTopMessageServiceImpl implements ChatTopMessageService {
    private final ChatTopMessageConvert chatTopMessageConvert;
    private final ChatTopMessageManager chatTopMessageManager;

    private final ChatGroupMessageService chatGroupMessageService;

    /**
     * 根据会话ID查询置顶消息
     *
     * @param targetId
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatTopMessageResultDTO> listByTargetId(String targetId) {
        CommonErrors.BAD_REQUEST.check(StringUtils.isNotEmpty(targetId), MessageUtils.message("chat.message.top.targetId.not.blank"));
        List<ChatTopMessageEntity> list = chatTopMessageManager.listByTargetId(targetId);
        return list.stream().map(chatTopMessageConvert::convert).collect(Collectors.toList());
    }

    /**
     * 消息置顶
     *
     * @param dto
     * @param user
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long topMessage(ChatMessageTopDTO dto, Account user) {
        ChatTopMessageEntity entity = chatTopMessageManager.infoByTargetIdAndMessageId(dto.getTargetId(), dto.getMessageId());
        if (Objects.nonNull(entity)) {
            return entity.getId();
        }
        Long count = chatTopMessageManager.countByTargetId(dto.getTargetId());
        if (Objects.equals(CodeUtil.ConversationType.PRIVATE.getName(), dto.getConversationType())) {
            //私聊置顶消息上限
            if (Objects.nonNull(count) && count >= ChatConstants.CHAT_PRIVATE_TOP_MESSAGE_LIMIT) {
                replaceLongest(user, dto.getTargetId());
            }
        } else if (Objects.equals(CodeUtil.ConversationType.GROUP.getName(), dto.getConversationType())) {
            //群聊置顶消息上限
            if (Objects.nonNull(count) && count >= ChatConstants.CHAT_GROUP_TOP_MESSAGE_LIMIT) {
                replaceLongest(user, dto.getTargetId());
            }
        }
        entity = chatTopMessageConvert.create(dto);
        entity.setTopTime(LocalDateTime.now());
        chatTopMessageManager.save(entity);
        if (Objects.equals(CodeUtil.ConversationType.GROUP.getName(), entity.getConversationType())) {
            //群组消息置顶小灰条通知消息
            chatGroupMessageService.sendTopMessage(user, dto.getTargetId());
        }
        return entity.getId();
    }

    /**
     * 取消置顶
     *
     * @param dto
     * @param user
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelTopMessage(ChatMessageCancelTopDTO dto, Account user) {
        ChatTopMessageEntity entity = chatTopMessageManager.infoByTargetIdAndMessageId(dto.getTargetId(), dto.getMessageId());
        if (Objects.isNull(entity)) {
             return Boolean.TRUE;
        }
        boolean flag = chatTopMessageManager.removeByTargetIdAndMessageId(dto.getTargetId(), dto.getMessageId());
        if (flag) {
            if (Objects.equals(CodeUtil.ConversationType.GROUP.getName(), entity.getConversationType())) {
                //群组取消消息置顶小灰条通知消息
                chatGroupMessageService.sendCancelTopMessage(user, entity.getTargetId());
            }
        }
        return flag;
    }

    /**
     * 置顶消息超上限，移除最久的置顶消息
     *
     * @param user
     * @param targetId
     */
    private void replaceLongest(Account user, String targetId) {
        //查询最久的置顶消息
        ChatTopMessageEntity longest = chatTopMessageManager.selectOneByTargetIdOrderByTopTime(targetId);
        if (Objects.isNull(longest)) {
            return;
        }
        boolean flag = chatTopMessageManager.removeByTargetIdAndMessageId(longest.getTargetId(), longest.getMessageId());
        if (flag) {
            if (Objects.equals(CodeUtil.ConversationType.GROUP.getName(), longest.getConversationType())) {
                //群组取消消息置顶小灰条通知消息
                chatGroupMessageService.sendCancelTopMessage(user, longest.getTargetId());
            }
        }
    }

}
